/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ipartek.formacion.gestformwww.controlador;

import com.ipartek.formacion.gestformwww.modelo.ModeloCorreo;
import com.ipartek.formacion.gestformwww.modelo.ModeloCurso;
import com.ipartek.formacion.gestformwww.modelo.ModeloDiaClase;
import com.ipartek.formacion.gestformwww.modelo.beans.Correo;
import com.ipartek.formacion.gestformwww.modelo.beans.Curso;
import com.ipartek.formacion.gestformwww.modelo.beans.DiaClase;
import com.ipartek.formacion.gestformwww.modelo.beans.InformeCorreo;
import com.ipartek.formacion.gestformwww.modelo.beans.excepciones.GestorFormacionExcepcion;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 *Clase que realiza la accion de enviar el calendario por correo
 * @author Ainhoa, revisado por Cristina y Fran.
 */
public class EnviarCalendarioCorreoAccion implements Accion {

    private final String visualizarcurso = "visualizar-curso-accion";
    private final String visualizarenviarcorreo = "visualizar-enviar-calendario-correo-accion";

    public AccionRouter ejecuta(HttpServlet servlet, HttpServletRequest request, HttpServletResponse response) {
        // Declaramos las variables con las que vamos a trabajar
        AccionRouter router = null;
        HttpSession session = request.getSession();
        AccionServlet as = (AccionServlet) servlet;
        ModeloCorreo mcorreo = (ModeloCorreo) servlet.getServletContext().getAttribute("ModeloCorreo");
        ModeloCurso mcurso = (ModeloCurso) servlet.getServletContext().getAttribute("ModeloCurso");
        ModeloDiaClase mdiaclase = (ModeloDiaClase) servlet.getServletContext().getAttribute("ModeloDiaClase");
        String aleatorio = (String) session.getAttribute("aleatorioEnviarMail");
        boolean enviarMail = true;

        // Comprobacion para el F5
        if (aleatorio != null) {
            if (request.getParameter("aleatorioEnviarEmail") != null) {
                if (request.getParameter("aleatorioEnviarEmail").equals(aleatorio)) {
                    enviarMail = false;
                } else {
                    session.setAttribute("aleatorioEnviarEmail", request.getParameter("aleatorioEnviarEmail"));
                }
            }
        } else {
            session.setAttribute("aleatorioEnviarEmail", request.getParameter("aleatorioEnviarEmail"));
        }

        // Definimos los datos del curso
        Calendar c =null;
        Calendar ultimoDia = null;
        int meses = 0;
        ArrayList<DiaClase> dias = null;
        Curso curso = null;
        Integer idCurso = Integer.parseInt(request.getParameter("idCurso"));

        // Definimos los datos de las clases del curso
        DiaClase actual = new DiaClase();
        Iterator<DiaClase> it=null;

        // Definimos las partes del email
        String asunto = request.getParameter("asunto");
        String mensaje = request.getParameter("textoemail");
        Timestamp fechaMail = new Timestamp((new Date()).getTime());
        Correo correo = null;
        ArrayList<String> mails = null;
        String tabla = "";
        ArrayList<String> errorm = new ArrayList<String>();
        ArrayList<InformeCorreo> informes = new ArrayList<InformeCorreo>();
        try {
            mails = mcurso.getMailsAlumnosCurso(idCurso);
        } catch (GestorFormacionExcepcion ex) {
            Logger.getLogger(EnviarCalendarioCorreoAccion.class.getName()).log(Level.SEVERE, null, ex);
        }
        // Comprobaciones del Asunto y Cuerpo del email
        if (!Verificador.esCorrecto(mensaje) && !Verificador.esCorrecto(asunto)) {
            errorm.add("error-mail-no-valido");
        }
        if (!errorm.isEmpty()) {
            enviarMail = false;
        }

        // Comprobamos que haya un usuario logueado, y nos encotremos en un curso correcto
        if (session.getAttribute("usuario") != null && idCurso != null && request.getMethod().equalsIgnoreCase("POST")) {
            try {
                // Instanciamos el curso del cual mandaremos el calendario
                curso = mcurso.visualizarCurso(idCurso);
            } catch (GestorFormacionExcepcion ex) {
                Logger.getLogger(EnviarCalendarioCorreoAccion.class.getName()).log(Level.SEVERE, null, ex);
            }
            // Recuperamos los datos acerca de las fechas de curso
            String fechaIni = Verificador.formatearFecha(curso.getCurFchaInReal());
            String fechaFin = Verificador.formatearFecha(curso.getCurFchaFinReal());
            String[] fI = fechaIni.split("/");
            int diaIni = Integer.parseInt(fI[0]);
            int mesIni = Integer.parseInt(fI[1]);
            int anyoIni = Integer.parseInt(fI[2]);
            String[] fF = fechaFin.split("/");
            int diaFin = Integer.parseInt(fF[0]);
            int mesFin = Integer.parseInt(fF[1]);
            int anyoFin = Integer.parseInt(fF[2]);
            meses = Verificador.mesesEntre(diaIni, mesIni, anyoIni, diaFin, mesFin, anyoFin);
            // Obtenemos el primer dia y la lista de dias que tiene el curso
            try {
                c = mdiaclase.getPrimerDia(idCurso);
                ultimoDia = mdiaclase.getUltimoDia(idCurso);
                //dias = mdiaclase.listarDiasClase(idCurso, c);
            } catch (GestorFormacionExcepcion ex) {
                Logger.getLogger(EnviarCalendarioCorreoAccion.class.getName()).log(Level.SEVERE, null, ex);
            }
            // Obtenemos el ultimo dia del curso y lo cambiamos hasta llegar al final del mes, para pintarlo
            Calendar aux=null;
            aux = (Calendar) ultimoDia.clone();
            aux.set(Calendar.DAY_OF_MONTH, aux.getActualMaximum(Calendar.DAY_OF_MONTH));
            boolean mesNuevo = false;
            
            // Empezamos a montar la tabla
            //tabla = "<table width='100%' border='1'>";
            // Recorremos los meses en los que se imparte el curso
            //mesFin = mesIni + meses;
            mesFin = mesFin + ((anyoFin - anyoIni)* 12);
            for (int i = mesIni; i < (mesFin + 1); i++) {
            //for (int i = 0; i < (meses + 1); i++) {
                try {
                    //Recogemos las clases/citas del mes
                    dias = mdiaclase.listarDiasClase(idCurso, c);
                } catch (GestorFormacionExcepcion ex) {
                    Logger.getLogger(EnviarCalendarioCorreoAccion.class.getName()).log(Level.SEVERE, null, ex);
                }
                //Recorremos las citas del mes con el Iterator
                actual = new DiaClase();
                it=dias.iterator();
                c.setFirstDayOfWeek(Calendar.MONDAY);
                it = dias.iterator();
                if (it.hasNext()) {
                    actual = it.next();
                }

                // Creamos la cabecera de cada mes
                String nombreMes = new SimpleDateFormat("MMMMMMMMMM").format(c.getTime());
                String nombreAnyo = new SimpleDateFormat("yyyy").format(c.getTime());
                tabla = tabla
                    + "<table width='100%' border='1'>"    
                    + "<tr>" + "<h3><center>" + nombreMes.toUpperCase() + " " + nombreAnyo + "</center></h3>" + "</tr>"
                    + "<tr>"
                        + "<th width='15%'><center>Lunes</center></th>"
                        + "<th width='15%'><center>Martes</center></th>"
                        + "<th width='15%'><center>Mi&eacute;rcoles</center></th>"
                        + "<th width='15%'><center>Jueves</center></th>"
                        + "<th width='15%'><center>Viernes</center></th>"
                        + "<th width='15%'><center>S&aacute;bado</center></th>"
                        + "<th width='15%'><center>Domingo</center></th>"
                    + "</tr>";
                mesNuevo = false;
                // Notificamos el mes en el que estamos, empezando por el lunes de la semana en la que empieza
                int mes = i-1;
                // Controlamos que al cambiar de año el contador de meses funcione
                if (mes > 11) {
                    mes = mes - 12;
                }
                c.set(Calendar.DAY_OF_MONTH, 1);
                c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
                // Mientras queden dias del mes en el que estamos...
                while(c.before(aux) && !mesNuevo){
                    // Recorremos cada semana del mes, pintando una celda por dia
                    for (int dia = 0; dia < 7; dia++) {
                        // si es Lunes, empieza la linea
                        if (c.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) {
                            tabla = tabla
                        + "<tr>";
                        }
                        if (c.get(Calendar.MONTH) == mes) { //Es día del mes actual dentro del curso
                            if (actual.comparar(c)) {//Hay día de clase
                                tabla = tabla
                                + "<td style='overflow: visible;";
                                if (actual.getConflicto()) {
                                    tabla = tabla + " background-color:red;";
                                } else {
                                    tabla = tabla + " background-color:chartreuse;";
                                }
                                    tabla = tabla + "'>";
                                    tabla = tabla
                                    + "<table width='100%'>"
                                        + "<tr>"
                                            + "<b>" + c.get(Calendar.DAY_OF_MONTH) +"</b>"
                                        + "</tr>"
                                        + "<tr>"
                                            + "<td style='overflow: visible;'>"
                                                    + "<span>"
                                                        + actual.getDatosDiaClaseCalendario()
                                                    + "</span>"
                                            + "</td>"
                                        + "</tr>"
                                    + "</table>"
                                + "</td>";
                            if (it.hasNext()) {
                                    actual = it.next();
                                }
                            } else if (Verificador.fechaEntre(new Timestamp(c.getTimeInMillis()), curso.getCurFchaInReal(), curso.getCurFchaFinReal())) {//No hay clase
                                tabla = tabla
                                + "<td style='overflow: visible;'>"
                                    + "<b>" + c.get(Calendar.DAY_OF_MONTH) +"</b>"
                                    +"<center><br><br><br></center>"
                                + "</td>";
                            } else {
                                tabla = tabla
                                + "<td style='overflow: visible; background-color: gray;'>"
                                    + "<b>" + c.get(Calendar.DAY_OF_MONTH) +"</b>"
                                    + "<center><br><br><br></center>"
                                + "</td>";
                            }
                        } else {//No es día del mes dentro del curso
                            tabla = tabla + "<td></td>";
                        }
                        // si es Domingo, se cierra la linea
                        if (c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
                            tabla = tabla + "</tr>";
                            
                        }
                        // Al introducir cada dia, se le suma 1 al contador
                        c.add(Calendar.DAY_OF_YEAR, 1);
                        // Al acabar el mes, se pinta el resto de la semana y se notifica que se cambia de mes
                        if (c.get(Calendar.DAY_OF_MONTH) == 1 && (c.get(Calendar.MONTH)!= mes)){
                            for (int d = dia; d < 6; d++){
                                tabla = tabla + "<td></td>";
                            }
                            tabla = tabla + "</tr>";
                            mesNuevo = true;
                            break;
                        }
                        //}
                    }
                }
            // Al acabar el mes, cerramos la tabla
            tabla = tabla + "</table>" + "<br>";
            }
            //Añadimos las observaciones como cuerpo del mensaje
            if (!mensaje.isEmpty()) {
                tabla = tabla + "<br>" + "<label><b>" + "Observaciones:" + "</b></label>";
            }

            if (enviarMail) {
                //Enviar Mail
                for (String email : mails) {
                    if (Verificador.esEmail(email)) {
                        //Enviar Mail
                        correo = new Correo();
                        correo.setDestinatario(email);
                        correo.setAsunto(asunto);
                        correo.setTabla(tabla);
                        correo.setCuerpo(mensaje);
                        correo.setCurId(idCurso);
                        correo.setFecha(fechaMail);

                        try {
                            mcorreo.envioCalendario(correo, servlet.getServletContext());
                        } catch (GestorFormacionExcepcion ex) {
                            Logger.getLogger(EnviarCorreoAccion.class.getName()).log(Level.SEVERE, null, ex);
                            request.setAttribute("errores", errorm);
                            try {
                                router = as.getFactory().getAction(as.getNombreClaseRecurso(visualizarcurso), servlet.getClass().getClassLoader()).ejecuta(servlet, request, response);
                            } catch (ClassNotFoundException ex1) {
                                Logger.getLogger(EnviarCorreoAccion.class.getName()).log(Level.SEVERE, null, ex1);
                            } catch (InstantiationException ex1) {
                                Logger.getLogger(EnviarCorreoAccion.class.getName()).log(Level.SEVERE, null, ex1);
                            } catch (IllegalAccessException ex1) {
                                Logger.getLogger(EnviarCorreoAccion.class.getName()).log(Level.SEVERE, null, ex1);
                            }
                        }
                        // Creamos los datos del informe
                        InformeCorreo inf = new InformeCorreo();
                        inf.setNombre("Administración");
                        inf.setApellidos("Ipartek");
                        inf.setDireccion(email);
                        inf.setAsunto(correo.getAsunto());
                        inf.setCuerpo(correo.getCuerpo());
                        inf.setEnviado(correo.isEnviado());
                        inf.setFecha(correo.getFecha());
                        informes.add(inf);

                        request.setAttribute("informe", informes);
                        request.setAttribute("contenido", "visualizar-informe-email");
                        request.setAttribute("idCurso", idCurso);
                        router = new AccionRouter("principal", true);
                    }
                }
            } else {
                request.setAttribute("errores", errorm);
                try {
                    router = as.getFactory().getAction(as.getNombreClaseRecurso(visualizarenviarcorreo), servlet.getClass().getClassLoader()).ejecuta(servlet, request, response);
                } catch (ClassNotFoundException ex) {
                    Logger.getLogger(EnviarCorreoAccion.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InstantiationException ex) {
                    Logger.getLogger(EnviarCorreoAccion.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IllegalAccessException ex) {
                    Logger.getLogger(EnviarCorreoAccion.class.getName()).log(Level.SEVERE, null, ex);
                }

            }
        } else {
            router = new AccionRouter("inicio");
        }
        return router;
    }
}
